package com.ys
{
	import com.ys.obj.AudioTrack;
	import com.ys.obj.Text;
	import com.ys.ui.Button;
	import com.ys.ui.Chooser;
	import com.ys.ui.SequenceTrack;
	import com.ys.util.Const;
	import com.ys.util.GraphicsUtil;
	import com.ys.util.SoundConst;
	
	import flash.display.Sprite;
	import flash.events.MouseEvent;
	import flash.events.TimerEvent;
	import flash.utils.Timer;
	
	import gs.TweenLite;
	
	public class BeatSequencerAS3 extends Sprite
	{
		private var w:Number = 800;
		private var h:Number = 500;
		
		public var chooser:Chooser;
		private var timer:Timer;
		
		private var bpm:int = 120;
		private var tempoCheck:Number = 0;
		private var counter:int;
		
		private var playing:Boolean = false;
		private var effectLayer:Sprite = new Sprite;
		
		public var sequences:Array = [];
		public var sequenceLayer:Sprite = new Sprite;
		private var audio:AudioTrack = new AudioTrack;
		
		private var beatObject:Object = new Object;
		
		public function BeatSequencerAS3():void
		{
			loadXML();
		}
		
		private function loadXML():void
		{			
			var xml:XML = SoundConst.XML_DATA;
			audio.load(xml);
			init();
			
			var color:uint = 0xcccccc;
			var bg:Sprite = GraphicsUtil.createBorderLine(w-1, h-1, color);
			var split1:int = 400;
			var split2:int = 450;
			bg.graphics.moveTo(0, split1);
			bg.graphics.lineTo(w, split1)
			bg.graphics.moveTo(100, split1);
			bg.graphics.lineTo(100, h)
			bg.graphics.moveTo(100, split2);
			bg.graphics.lineTo(w, split2)
			addChild(bg);
		}
		
		private function init():void
		{
			addChild(effectLayer);
			addAssets();
			addChild(sequenceLayer);
			var seq:SequenceTrack;
			
			for (var i:int = 0; i < 1; i++)
			{
				seq = new SequenceTrack;
				seq.x = Const.PADDING;
				seq.y = i*Const.SEQUENCE_GAP + Const.PADDING_TOP;
				sequenceLayer.addChild(seq);
				
				seq.filters = [Const.DEFAULT_FILTER];
				
				sequences.push(seq);
			}
			
			
			chooser = new Chooser(w, h);
			addChild(chooser);
			
		}
		
		private function addSequence(e:MouseEvent=null):void
		{
			if (sequences.length < 4)
			{
				var seq:SequenceTrack = new SequenceTrack;
				seq.x = Const.PADDING;
				seq.y = sequences.length*Const.SEQUENCE_GAP + Const.PADDING_TOP;
				sequenceLayer.addChild(seq);
				
				seq.filters = [Const.DEFAULT_FILTER];
				
				sequences.push(seq);
			}
		}
		
		private function addAssets():void 
		{
			var playBtn:Button = new Button(50,Const.DEFAULT_COLOR);
			playBtn.addChild( GraphicsUtil.createAssetSprite( Const.LIB_PLAY ) );
			playBtn.x = 50;
			playBtn.y = 450;
			addChild(playBtn);			
			playBtn.addEventListener(MouseEvent.CLICK, onPlayClick);
			
			
			var addBtn:Button = new Button(20,Const.DEFAULT_COLOR);
			addBtn.addChild( GraphicsUtil.createAssetSprite( Const.LIB_PLUS ) );
			addBtn.x = 125;
			addBtn.y = 425;
			addChild(addBtn);			
			addBtn.addEventListener(MouseEvent.CLICK, addSequence);
			
			var bpmInput:Text = new Text;
			bpmInput.height = 20;
			bpmInput.width = 100;
			bpmInput.x = 140;
			bpmInput.y = 465;
			bpmInput.text = '120 bpm';
			addChild(bpmInput);
			
			var bpmUp:Button = new Button(20,Const.DEFAULT_COLOR);
			bpmUp.addChild( GraphicsUtil.createAssetSprite( Const.LIB_PLUS ) );
			bpmUp.x = 210;
			bpmUp.y = 475;
			addChild(bpmUp);
			bpmUp.addEventListener(MouseEvent.CLICK, onBpmClick);
			
			var bpmDown:Button = new Button(20,Const.DEFAULT_COLOR);
			bpmDown.addChild( GraphicsUtil.createAssetSprite( Const.LIB_MINUS ) );
			bpmDown.x = 125;
			bpmDown.y = 475;
			addChild(bpmDown);
			bpmDown.addEventListener(MouseEvent.CLICK, onBpmClick);
			
			playBtn.filters = addBtn.filters = bpmDown.filters = bpmUp.filters = bpmInput.filters = [Const.DEFAULT_FILTER];
			
			
			function onBpmClick(e:MouseEvent):void
			{
				var tempBpm:int = bpm;
				
				if (e.target == bpmUp)
				{
					tempBpm += 10;
				} 
				else
				{
					tempBpm -= 10;
				}
				
				if (tempBpm < 30)
				{
					tempBpm = 30;
				}
				else if(tempBpm > 200)
				{
					tempBpm = 200;
				}
				bpm = tempBpm;
				
				bpmInput.text = bpm.toString() + ' bpm';
			}
		}
		
		private function onPlayClick(e:MouseEvent):void
		{
			if (!playing)
			{
				playing = true;
				play();
			}
			else
			{
				playing = false;
				stop();
			}
		}
		
		private function play():void
		{
			//timer = new Timer(0);
			/*timer.addEventListener(TimerEvent.TIMER, timerCheck);
			tempoCheck = ( (100*(bpm/60) )/4);
			counter = 0;
			timer.start();*/
			TweenLite.killTweensOf(beatObject);
			counter = 0;
			beat();
		}
		
		private function stop():void
		{
			//timer.stop();
			//timer.removeEventListener(TimerEvent.TIMER, timerCheck);
			TweenLite.killTweensOf(beatObject);
		}
		
		private function timerCheck(e:TimerEvent):void
		{
			if (timer.currentCount >= tempoCheck)
			{
				timer.reset();
				timer.start();
				beat();
			}
		}
		
		private function beat():void
		{
			var circle:Sprite;	
			var sequence:SequenceTrack;
			var btn:Button;
			var note:String;
			var color:uint;
			var size:int;
			var volume:Number;
			
			for (var i:int = 0; i < sequences.length; i++)
			{
				sequence = sequences[i];
				btn = sequence.sequenceItems[counter];
				color = Const.DEFAULT_COLOR;
				size = 10;
				volume = sequence.volume;
				
				if (btn.textField.text && btn.textField.text != '')
				{
					note = sequence.mainButton.textField.text + btn.textField.text.toUpperCase();
					audio.play(note, volume);
					color = Const.HIGHIGHT_COLOR;
					size = 20;
				
					circle = GraphicsUtil.createPop(effectLayer, size, color, volume);
					circle.x = Const.PADDING + Const.PADDING_INNER + counter*Const.BUTTON_SPACER + Const.PADDING_OFFSET;
					circle.y = Const.PADDING_TOP + i*Const.SEQUENCE_GAP;
				}
			}
			
			
			var line:Sprite = GraphicsUtil.createLine(effectLayer,400);
			line.x = Const.PADDING + Const.PADDING_INNER + counter*Const.BUTTON_SPACER + Const.PADDING_OFFSET;
			line.y = 0;
	
			counter++;
			if (counter >= 16)
			{
				counter = 0;
			}
			
			TweenLite.to(beatObject, 60/bpm, {onComplete:beat});
		}

	}
}